package com.framework.test.utils;

import com.framework.test.core.CustomProcessor;
import com.framework.test.exceptions.AutomationException;
import com.framework.test.utils.ConfigurationManager;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.commons.dbutils.BasicRowProcessor;
import org.apache.commons.dbutils.BeanProcessor;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;

public class DBUtil {

    private final QueryRunner queryRunner;
    private final BeanProcessor beanProcessor;

    private DBUtil(DataSource dataSource) {
        this.queryRunner = new QueryRunner(dataSource);
        this.beanProcessor = new CustomProcessor();
    }

    public static DBUtil getInstance(String databaseName) {
        try {
            return new DBUtil(createDataSource(databaseName));
        } catch (AutomationException e) {
            throw new RuntimeException(e);
        }
    }

    // 查询单个对象
    public <T> T queryOne(String sql, Class<T> clazz, Object... params) throws SQLException {
        return queryRunner.query(sql, new BeanHandler<>(clazz, new BasicRowProcessor(beanProcessor)), params);
    }

    // 查询多个对象
    public <T> List<T> queryList(String sql, Class<T> clazz, Object... params) throws SQLException {
        return queryRunner.query(sql, new BeanListHandler<>(clazz, new BasicRowProcessor(beanProcessor)), params);
    }

    // 更新操作（增删改）, 返回受影响的行数
    public int update(String sql, Object... params) throws SQLException {
        return queryRunner.update(sql, params);
    }

    // 查询单个值
    public <T> T queryScalar(String sql, Object... params) throws SQLException {
        return queryRunner.query(sql, new ScalarHandler<>(), params);
    }

    private static DataSource createDataSource(String databaseName) throws AutomationException {

        String prefix = databaseName + ".";
        String jdbcUrl = ConfigurationManager.getProperty(prefix + "jdbcUrl");
        String username = ConfigurationManager.getProperty(prefix + "username");
        String password = ConfigurationManager.getProperty(prefix + "password");

        HikariConfig config = new HikariConfig();
        config.setJdbcUrl(jdbcUrl);
        config.setUsername(username);
        config.setPassword(password);
        return new HikariDataSource(config);
    }
}